#pragma once


#include <iostream>
#include <string>
#include <cstdlib>
#include <pthread.h>


class Thread
{
public:
    typedef enum{
        NEW = 0,
        RUNNING,
        EXITED,
    } ThreadStatus;
    typedef void* (*fun_c)(void*);
public:
    Thread(int num,fun_c func,void* args):_tid(0),_func(func),_args(args),_status(NEW)
    {
        char name[64];
        snprintf(name,sizeof(name),"thread-%d",num);
        _name = name;
    }
    int status(){return _status;}
    std::string threadname(){return _name;}
    pthread_t threadid()
    {
        if(_status==RUNNING)
        {
            return _tid;
        }else{
            return 0;
        }
    }
    static void* RunHelper(void* args)
    {
        Thread* td = static_cast<Thread*>(args);
        (*td)();
    }
    void operator()()
    {
        _func(_args);
    }
    void run()
    {
       int n =  pthread_create(&_tid,nullptr,RunHelper,this);
        if(n!=0)exit(1);
        _status = RUNNING;
    }
    void join()
    {
        int n = pthread_join(_tid,nullptr);
        if(n!=0)
        {
            std::cerr<<"main thread join thread"<<_name<<"error"<<std::endl;
            return;
        }
        _status = EXITED;
    }
private:
    pthread_t _tid;
    std::string _name;
    fun_c _func;
    void* _args;
    ThreadStatus _status;
};